package org.jeecg.modules.business.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.modules.business.entity.BusHousePriceSchemeLayout;
import org.jeecg.modules.business.entity.BusRoomsLivingOrder;
import org.jeecg.modules.business.entity.BusSchemeLayoutDailyPrice;
import org.jeecg.modules.business.mapper.BusSchemeLayoutDailyPriceMapper;
import org.jeecg.modules.business.service.IBusHousePriceSchemeLayoutService;
import org.jeecg.modules.business.service.IBusSchemeLayoutDailyPriceService;
import org.jeecg.modules.rooms.entity.CesHousePriceScheme;
import org.jeecg.modules.rooms.service.CesHousePriceSchemeServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 房价方案-每日房价表
 * @Author: jeecg-boot
 * @Date:   2023-04-08
 * @Version: V1.0
 */
@Service
public class BusSchemeLayoutDailyPriceServiceImpl extends ServiceImpl<BusSchemeLayoutDailyPriceMapper, BusSchemeLayoutDailyPrice> implements IBusSchemeLayoutDailyPriceService {

    @Autowired
    private IBusHousePriceSchemeLayoutService busHousePriceSchemeLayoutService;
    @Resource
    private CesHousePriceSchemeServiceImpl housePriceSchemeService;
    @Resource
    private RedisUtil redisUtil;

    @Override
    public List<BusSchemeLayoutDailyPrice> getDailyPrice(String schemeLayoutId, Date realDate) {
        QueryWrapper<BusSchemeLayoutDailyPrice> queryWrapper = new QueryWrapper<>();
        LoginUser user = TokenUtils.getAuthUser();
        if(user.getRelTenantIds() != null && !user.getRelTenantIds().equals("")){
            queryWrapper.eq("tenant_id",user.getRelTenantIds());
        }
        queryWrapper.eq("scheme_layout_id",schemeLayoutId);
        queryWrapper.eq("del_flag",0);
        List<BusSchemeLayoutDailyPrice> list = list(queryWrapper);
        //获取从今天开始，10天时间的数据
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date startDate = calendar.getTime();
        calendar.add(Calendar.DATE, 9);
        Date endDate = calendar.getTime();

        List<Date> lDate = findDates(startDate, endDate);
        if (realDate != null){
            lDate = findDates(realDate, endDate);
        }
        List<BusSchemeLayoutDailyPrice> newList = new ArrayList<>();
        BusHousePriceSchemeLayout busHousePriceSchemeLayout = busHousePriceSchemeLayoutService.getById(schemeLayoutId);
        if (list !=null && list.size() >= 0){
            lDate.forEach(day->{
                BusSchemeLayoutDailyPrice dayMoney = new BusSchemeLayoutDailyPrice();
                dayMoney.setSchemeLayoutId(schemeLayoutId);
                int flag = 0;
                for(BusSchemeLayoutDailyPrice s: list){
                    if(format.format(day).equals(format.format(s.getDate()))){
                        flag= 1;
                        dayMoney.setMoney(s.getMoney());
                        dayMoney.setId(s.getId());
                        dayMoney.setDate(s.getDate());
                    }
                }
                if (flag == 0){
                    dayMoney.setMoney(busHousePriceSchemeLayout.getMoney());
                    dayMoney.setId("");
                    dayMoney.setDate(day);
                }
                newList.add(dayMoney);
            });
        }else{
            lDate.forEach(day->{
                BusSchemeLayoutDailyPrice dayMoney = new BusSchemeLayoutDailyPrice();
                dayMoney.setSchemeLayoutId(schemeLayoutId);
                dayMoney.setMoney(busHousePriceSchemeLayout.getMoney());
                dayMoney.setId("");
                dayMoney.setDate(day);
                newList.add(dayMoney);
            });
        }
        return newList;
    }

    @Override
    public BigDecimal getOneDayPrice(String layoutId, BusRoomsLivingOrder livingOrder, Date date) {
        LambdaQueryWrapper<CesHousePriceScheme> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CesHousePriceScheme::getHotelId,livingOrder.getHotelId());
        queryWrapper.eq(CesHousePriceScheme::getInvalid,false);
        queryWrapper.eq(CesHousePriceScheme::getOpen,1);
        queryWrapper.and(e -> e.le(CesHousePriceScheme::getValidStartTime, LocalDate.now())
                .ge(CesHousePriceScheme::getValidEndTime, LocalDate.now()).or().eq(CesHousePriceScheme::getValidTime, 0));
        List<CesHousePriceScheme> cesHousePriceSchemes = housePriceSchemeService.list(queryWrapper);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        Optional<CesHousePriceScheme> schemeOptional = cesHousePriceSchemes.stream().filter(e -> e.getId().equals(livingOrder.getRoomPriceSlnId())).findFirst();
        if (schemeOptional.isPresent()) {
            return getMoney(layoutId, livingOrder.getRoomPriceSlnId(), calendar.getTime());
        }
        // 节假日方案
        Optional<CesHousePriceScheme> holidaySchemeOptional = cesHousePriceSchemes.stream().filter(e -> e.getSchemeType() == 2).findFirst();
        if (holidaySchemeOptional.isPresent()){
            String holidayStr = holidaySchemeOptional.get().getHoliday();
            String[] holidayArr = holidayStr.split(",");
            for (String s : holidayArr) {
                String[] holidays = s.split("~");
                DateTime start = DateUtil.parse(holidays[0], "yyyy-MM-dd");
                DateTime end = DateUtil.parse(holidays[1], "yyyy-MM-dd");
                if (start.isBefore(new Date()) && end.isAfter(new Date())){
                    return getMoney(layoutId, holidaySchemeOptional.get().getId(),calendar.getTime());
                }
            }
        }
        // 周末方案
        Optional<CesHousePriceScheme> weekSchemeOptional = cesHousePriceSchemes.stream().filter(e -> e.getSchemeType() == 1).findFirst();
        if (weekSchemeOptional.isPresent()){
            String weekStr = weekSchemeOptional.get().getWeekend();
            String[] weekArr = weekStr.split(",");
            int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
            String todayWeek = (week == 0 ? 7 : week)  + "";
            boolean contains = Arrays.asList(weekArr).contains(todayWeek);
            if (contains){
                return getMoney(layoutId, weekSchemeOptional.get().getId(),calendar.getTime());
            }
        }
        // 平日方案
        Optional<CesHousePriceScheme> normalSchemeOptional = cesHousePriceSchemes.stream().filter(e -> e.getSchemeType() == 0).findFirst();
        return getMoney(layoutId, normalSchemeOptional.get().getId(), calendar.getTime());
    }

    public BigDecimal getMoney(String layoutId, String schemeId, Date date){
        BusHousePriceSchemeLayout housePriceSchemeLayout = busHousePriceSchemeLayoutService.getOne(Wrappers
                .<BusHousePriceSchemeLayout>lambdaQuery().eq(BusHousePriceSchemeLayout::getLayoutId, layoutId)
                .eq(BusHousePriceSchemeLayout::getSchemeId, schemeId).last("limit 1"));
        if (housePriceSchemeLayout == null) {
            return null;
        }
        BusSchemeLayoutDailyPrice dailyPrice = getOne(Wrappers.<BusSchemeLayoutDailyPrice>lambdaQuery()
                .eq(BusSchemeLayoutDailyPrice::getSchemeLayoutId, housePriceSchemeLayout)
                .eq(BusSchemeLayoutDailyPrice::getDate, date).last("limit 1"));
        if (dailyPrice != null) {
            return dailyPrice.getMoney();
        }
        return housePriceSchemeLayout.getMoney();
    }

    public static List<Date> findDates(Date dBegin, Date dEnd){
        List lDate = new ArrayList();
        lDate.add(dBegin);
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime()))
        {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            lDate.add(calBegin.getTime());
        }
        return lDate;
    }

}
